home *** CD-ROM | disk | FTP | other *** search
- ///--------------------------------------------------------------------------------------
- // Platform Scrolling.c
- //
- // By Vern Jensen. Created in September, 1997.
- ///--------------------------------------------------------------------------------------
-
-
- #include <SWFPSReport.h>
- #include <SWIncludes.h>
- #include <SWGameUtils.h>
- #include <SWApplication.h>
-
- #include "Platform Scrolling.h"
-
-
- #define kFullScreenWindow true // Toggles between 512x384 and 640x480
- #define kWorldRectInset 0 // Make the SpriteWorld smaller?
- #define kInterlacedMode false // Turns Interlaced mode on/off
- #define kSyncToVBL false // Sync SpriteWorld to VBL?
- #define kMaxFPS 30 // Set to 0 for unrestricted speed
-
-
- #define kWalkIncrease 1
- #define kMaxWalkSpeed 10
- #define kMaxFallSpeed 20
- #define kJumpSpeed 26
- #define kMaxSpriteJumpDistance 19 // How many frames the sprite can keep going up
- #define kGravitySpeed 2
-
- #define kMovingFloorSpeed 0 // How often the moving floors change frames
- #define kMovingFloorForce 2 // How far they move the sprite when the move
- #define kChangingFloorSpeed 5 // Frame rate of the changing floor
- #define kChangingFloorWait 120 // How long of a delay between on/off
- #define kSpikeSpeed 2 // How fast the spikes move
- #define kSpikeChangeDelay 150 // How long they wait between moves
- #define kExitSignSpeed 8 // Animation speed of exit sign
- #define kArrowSpeed 10 // Animation speed of arrow
-
- #define kRunningCorrection 7 // Determines how many pixel a sprite can fall through
- // the top of a tile and still be put back on top.
- // Useful for running across tiles with holes inbetween.
-
- #define kSpriteMoveDistance 80 // How far the sprite can move from
- // the center of the screen, in pixels.
- // Try making this value higher!
-
-
- #define kTileWidth 40
- #define kTileHeight 40
-
-
- #define kStartRow 5 // Starting position of sprite
- #define kStartCol 5 // in tile col and row
-
-
- #define kLeftArrowKey 0x7B
- #define kRightArrowKey 0x7C
- #define kDownArrowKey 0x7D
- #define kUpArrowKey 0x7E
-
- #define kLeftKeyPad 0x56
- #define kRightKeyPad 0x58
- #define kDownKeyPad 0x54
- #define kUpKeyPad 0x5B
-
- #define kEscKey 0x35
-
-
- enum tileIDs
- {
- kFirstWallTile = 0,
- kLastWallTile = 9,
- kFirstSpikeTile,
- kLastSpikeTile = kFirstSpikeTile + 15,
- kBackgroundTile,
- kFirstLeftFloorTile,
- kLastLeftFloorTile = kFirstLeftFloorTile + 4,
- kFirstRightFloorTile,
- kLastRightFloorTile = kFirstRightFloorTile + 4,
- kFirstChangingTile,
- kLastChangingTile = kFirstChangingTile + 2,
- kFirstBackgroundTile,
- kLastBackgroundTile = kFirstBackgroundTile + 8,
- kFirstExitTile,
- kLastExitTile = kFirstExitTile + 2,
- kMaxNumTiles
- };
-
-
-
-
- /***********/
- /* Globals */
- /***********/
-
- SpriteWorldPtr gSpriteWorldP;
- SpriteLayerPtr gSpriteLayerP;
- TileMapStructPtr gTileMapStructP;
- TileMapPtr gTileMap;
- SpritePtr gSimpleSpriteP;
- WindowPtr gWindowP;
- short gCurrentLevel = 128;
- Rect gScreenMidRect, gSpriteInsetRect;
- Boolean gSpriteCanJump, gSpriteIsJumping, gSpriteJumpStage;
- Boolean gChangingFloorMode = true;
- Boolean gDone = false;
- Boolean gEscapeKey = false;
- Boolean gSpikesAreUp = true;
- Boolean gSpriteHitExit = false, gSpriteWasKilled = false;
-
- struct moveKeys
- {
- Boolean up;
- Boolean right;
- Boolean down;
- Boolean left;
- Boolean jump;
- } gKeys;
-
-
- ///--------------------------------------------------------------------------------------
- // Main
- ///--------------------------------------------------------------------------------------
-
- void main( void )
- {
- Initialize(kNumberOfMoreMastersCalls);
-
- if (SWHasSystem7())
- {
- AllowKeyUpEvents(); // Part of SWGameUtils.c
- SetCursor(*GetCursor(watchCursor));
-
- CreateWindow();
- CreateSpriteWorld();
- CreateBallSprite();
- SWLockSpriteWorld(gSpriteWorldP);
-
- SetCursor(&qd.arrow);
- HideCursor();
-
- SetUpAnimation();
- RunAnimation();
- ShutDown();
-
- RestoreEventMask(); // Call this after AllowKeyUpEvents
- }
- else
- {
- CantRunOnThisMachine();
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateWindow
- ///--------------------------------------------------------------------------------------
-
- void CreateWindow( void )
- {
- Rect windRect;
- RgnHandle mBarUpdateRgn;
-
- gWindowP = GetNewCWindow(128, NULL, (WindowPtr)-1L);
-
- if (gWindowP == NULL)
- {
- CantFindResource();
- }
- else
- {
- if (kFullScreenWindow)
- {
- SizeWindow(gWindowP, SW_MIN(640, qd.screenBits.bounds.right),
- SW_MIN(480, qd.screenBits.bounds.bottom), false);
- }
- else
- {
- SizeWindow(gWindowP, 512, 384, false);
- }
-
- // Center window in screen
- windRect = gWindowP->portRect;
- CenterRect(&windRect, &qd.screenBits.bounds);
-
- // Make sure window is aligned to long-word boundaries (for 8-bit mode)
- windRect.left = windRect.left>>2<<2;
-
- MoveWindow(gWindowP, windRect.left, windRect.top, false);
- ShowWindow(gWindowP);
- SetPort(gWindowP);
- }
-
- mBarUpdateRgn = SWHideMenuBar(gWindowP);
- EraseRgn(mBarUpdateRgn);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- void CreateSpriteWorld( void )
- {
- Rect offscreenRect, worldRect;
- OSErr err;
-
-
- err = SWEnterSpriteWorld();
- FatalError(err);
-
-
- worldRect = gWindowP->portRect;
- InsetRect(&worldRect, kWorldRectInset, kWorldRectInset);
-
-
- // Set size of offscreen area
- offscreenRect = worldRect;
- OffsetRect(&offscreenRect, -offscreenRect.left, -offscreenRect.top);
-
-
- // Make offscreen area evenly divisible by tile width & height
- if ( (offscreenRect.right/kTileWidth)*kTileWidth != offscreenRect.right)
- offscreenRect.right = (offscreenRect.right/kTileWidth)*kTileWidth + kTileWidth;
-
- if ( (offscreenRect.bottom/kTileHeight)*kTileHeight != offscreenRect.bottom)
- offscreenRect.bottom = (offscreenRect.bottom/kTileHeight)*kTileHeight + kTileHeight;
-
- // Create the scrolling sprite world
- err = SWCreateSpriteWorldFromWindow(&gSpriteWorldP, (CWindowPtr)gWindowP,
- &worldRect, &offscreenRect, 0);
- FatalError(err);
-
- // Create the sprite layer
- err = SWCreateSpriteLayer(&gSpriteLayerP);
- FatalError(err);
-
- // Add it to the world
- SWAddSpriteLayer(gSpriteWorldP, gSpriteLayerP);
-
-
- err = SWInitTiling(gSpriteWorldP, kTileHeight, kTileWidth, kMaxNumTiles);
- FatalError(err);
-
- err = SWLoadTileMap(&gTileMapStructP, gCurrentLevel);
- FatalError(err);
-
- SWInstallTileMap(gSpriteWorldP, gTileMapStructP, 0);
- gTileMap = gTileMapStructP->tileMap;
-
- // Load first set of tiles
- err = SWLoadTilesFromPictResource(
- gSpriteWorldP,
- 0, // startTileID
- kMaxNumTiles-1, // endTileID
- 200, // pictResID
- 0, // maskResID
- kNoMask, // maskType
- 0, // horizBorderWidth
- 0); // vertBorderHeight
- FatalError(err);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateBallSprite
- ///--------------------------------------------------------------------------------------
-
- void CreateBallSprite( void )
- {
- OSErr err;
-
- // Create the ball sprite
- err = SWCreateSpriteFromSinglePict(gSpriteWorldP, &gSimpleSpriteP, NULL,
- 128, 128, 40, 0, kFatMask);
- FatalError(err);
-
- // Set up the ball sprite
- SWLockSprite(gSimpleSpriteP);
- SWAddSprite(gSpriteLayerP, gSimpleSpriteP);
- SWSetSpriteMoveProc(gSimpleSpriteP, KeySpriteMoveProc);
- SWSetSpriteMoveDelta(gSimpleSpriteP, 0, 0);
- SWSetSpriteLocation(gSimpleSpriteP, kStartCol * kTileWidth, kStartRow * kTileHeight);
-
-
- // SWSetSpriteLocation(gSimpleSpriteP, 51 * kTileWidth-5, 7 * kTileHeight);
-
-
-
- // Inset for left, top, right, and bottom of sprite when checking sprite with tiles
- SetRect(&gSpriteInsetRect, 5, 4, 5, 0);
- gSpriteCanJump = true;
- gSpriteIsJumping = false;
- gSpriteJumpStage = 0;
-
-
- // Set the sprite's drawProc
- if (gSpriteWorldP->pixelDepth == 8) // If in 256 colors
- {
- if (kInterlacedMode)
- SWSetSpriteDrawProc(gSimpleSpriteP, BP8BitInterlacedMaskDrawProc);
- else
- SWSetSpriteDrawProc(gSimpleSpriteP, BlitPixie8BitMaskDrawProc);
- }
- else if ( !(SW_PPC && gSpriteWorldP->pixelDepth < 8) ) // Not 256 colors
- {
- // Use interlaced drawProcs unless in B&W, where interlacing is ugly
- if (kInterlacedMode && gSpriteWorldP->pixelDepth > 2)
- SWSetSpriteDrawProc(gSimpleSpriteP, BPAllBitInterlacedMaskDrawProc);
- else
- SWSetSpriteDrawProc(gSimpleSpriteP, BlitPixieAllBitMaskDrawProc);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SetUpAnimation
- ///--------------------------------------------------------------------------------------
-
- void SetUpAnimation( void )
- {
- Rect moveBoundsRect;
-
- ResetKeys();
-
- // Set up data used by the SmoothScrollingWorldMoveProc
- gScreenMidRect = gSimpleSpriteP->curFrameP->frameRect;
- CenterRect( &gScreenMidRect, &gSpriteWorldP->backRect );
-
- SWSetSpriteWorldMaxFPS(gSpriteWorldP, kMaxFPS);
- SWSyncSpriteWorldToVBL(gSpriteWorldP, kSyncToVBL);
- SWSetCleanUpSpriteWorld(gSpriteWorldP);
-
- // movement boundary = size of tileMap
- SetRect(&moveBoundsRect, 0, 0,
- gTileMapStructP->numCols * kTileWidth,
- gTileMapStructP->numRows * kTileHeight);
-
- SWSetTileChangeProc(gSpriteWorldP, TileChangeProc);
- SWSetScrollingWorldMoveBounds(gSpriteWorldP, &moveBoundsRect);
- SWSetScrollingWorldMoveProc(gSpriteWorldP, SmoothScrollingWorldMoveProc, gSimpleSpriteP);
-
- // Move visScrollRect to starting sprite position
- SWMoveVisScrollRect(gSpriteWorldP,
- gSpriteWorldP->followSpriteP->destFrameRect.left - gSpriteWorldP->backRect.right/2,
- gSpriteWorldP->followSpriteP->destFrameRect.top - gSpriteWorldP->backRect.bottom/2);
-
- if (gSpriteWorldP->pixelDepth == 8) // If in 256 colors
- {
- if (kInterlacedMode)
- {
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BP8BitInterlacedRectDrawProc);
- SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BP8BitInterlacedRectDrawProc);
- SWSetPartialMaskDrawProc(gSpriteWorldP, BP8BitInterlacedPartialMaskDrawProc);
- SWSetDoubleRectDrawProc(gSpriteWorldP, BP8BitInterlacedDoubleRectDrawProc);
- }
- else
- {
- SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixie8BitRectDrawProc);
- SWSetPartialMaskDrawProc(gSpriteWorldP, BlitPixie8BitPartialMaskDrawProc);
- SWSetDoubleRectDrawProc(gSpriteWorldP, BlitPixie8BitDoubleRectDrawProc);
- }
- } // When running on PPC, we can't use the AllBit blitters in lower than 8-bit
- else if ( !(SW_PPC && gSpriteWorldP->pixelDepth < 8) ) // Not 256 colors
- {
- if (kInterlacedMode && gSpriteWorldP->pixelDepth > 2)
- {
- // Use interlaced drawProcs unless in B&W, where interlacing is ugly
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BPAllBitInterlacedRectDrawProc);
- SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BPAllBitInterlacedRectDrawProc);
- SWSetPartialMaskDrawProc(gSpriteWorldP, BPAllBitInterlacedPartialMaskDrawProc);
- if (gSpriteWorldP->pixelDepth == 16)
- SWSetDoubleRectDrawProc(gSpriteWorldP, BP16BitInterlacedDoubleRectDrawProc);
- }
- else
- {
- SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
- SWSetPartialMaskDrawProc(gSpriteWorldP, BlitPixieAllBitPartialMaskDrawProc);
- if (gSpriteWorldP->pixelDepth == 16)
- SWSetDoubleRectDrawProc(gSpriteWorldP, BlitPixie16BitDoubleRectDrawProc);
- }
- }
-
-
- // Make sure CopyBits, if used, doesn't try to colorize things
- SWSetPortToWindow(gSpriteWorldP);
- ForeColor(blackColor);
- BackColor(whiteColor);
-
- SWDrawTilesInBackground(gSpriteWorldP);
- SWUpdateScrollingSpriteWorld(gSpriteWorldP, true);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // RunAnimation
- ///--------------------------------------------------------------------------------------
-
- void RunAnimation( void )
- {
- unsigned long frames;
-
- frames = 0;
- StartTimer();
-
- gEscapeKey = false;
-
- FatalError( SWStickyError() ); // Make sure no errors got past us during setup
-
- while (!Button() && !gEscapeKey)
- {
- SWProcessScrollingSpriteWorld(gSpriteWorldP);
- FatalError( SWStickyError() ); // Make sure no errors occurred during a MoveProc, etc.
- SWAnimateScrollingSpriteWorld(gSpriteWorldP);
-
- // We call this in case the Control Strip or something changes our window's visRgn
- KeepMenuBarHidden(gWindowP);
-
- if (gSpriteWorldP->frameHasOccurred)
- {
- frames++;
-
- if (gSpriteHitExit)
- AdvanceLevel();
- else if (gSpriteWasKilled)
- KillSprite();
- }
- }
-
-
- SWShowMenuBar(gWindowP);
- ShowResults(frames);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ShutDown (clean up and dispose of the SpriteWorld)
- ///--------------------------------------------------------------------------------------
-
- void ShutDown( void )
- {
- SWDisposeSpriteWorld(&gSpriteWorldP);
- SWExitSpriteWorld();
-
- FlushEvents(everyEvent, 0);
- ShowCursor();
- }
-
-
- ///--------------------------------------------------------------------------------------
- // KeySpriteMoveProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void KeySpriteMoveProc(SpritePtr srcSpriteP)
- {
- short horizDir, tempHorizDelta;
- Boolean spriteIsOnGround = false;
-
- UpdateKeys(); // Put the latest key values in the keys structure
-
-
- // See if the sprite is standing on a wall
- spriteIsOnGround = false;
- if ( ((srcSpriteP->destFrameRect.bottom - gSpriteInsetRect.bottom) / kTileHeight) *
- kTileHeight == srcSpriteP->destFrameRect.bottom - gSpriteInsetRect.bottom )
- {
- gSpriteInsetRect.bottom--; // Check one line lower than bottom of sprite
-
- if (SWCheckSpriteWithTiles(gSpriteWorldP, srcSpriteP, kSWBottomSide,
- &gSpriteInsetRect, 0, 0, kFirstWallTile, kLastWallTile, false) ||
- SWCheckSpriteWithTiles(gSpriteWorldP, srcSpriteP, kSWBottomSide,
- &gSpriteInsetRect, 0, 0, kFirstLeftFloorTile, kLastChangingTile, false) )
- {
- spriteIsOnGround = true;
- }
-
- gSpriteInsetRect.bottom++; // Change rect to the way it was before
- }
-
-
- horizDir = (gKeys.right - gKeys.left);
-
- if (horizDir) // Are we moving left or right?
- {
- // Did we change direction?
- if ( (srcSpriteP->horizMoveDelta > 0 && horizDir < 0) ||
- (srcSpriteP->horizMoveDelta < 0 && horizDir > 0) )
- {
- srcSpriteP->horizMoveDelta = 0;
- }
-
- // Add speed to sprite
- srcSpriteP->horizMoveDelta += horizDir * kWalkIncrease;
-
- // Keep from moving too fast
- if (srcSpriteP->horizMoveDelta > kMaxWalkSpeed)
- srcSpriteP->horizMoveDelta = kMaxWalkSpeed;
- else if (srcSpriteP->horizMoveDelta < -kMaxWalkSpeed)
- srcSpriteP->horizMoveDelta = -kMaxWalkSpeed;
- }
- else // We're not moving, so slow down
- {
- if (srcSpriteP->horizMoveDelta > 0)
- srcSpriteP->horizMoveDelta /= 2;
- else if (srcSpriteP->horizMoveDelta < 0)
- srcSpriteP->horizMoveDelta /= 2;
- }
-
-
- if (gKeys.up && gSpriteIsJumping) // Already jumping - continue going up
- {
- if (gSpriteJumpStage++ < kMaxSpriteJumpDistance)
- {
- srcSpriteP->vertMoveDelta = -kJumpSpeed + gSpriteJumpStage * 1.4;
- }
- else
- {
- gSpriteIsJumping = false;
- }
- }
- else if (gKeys.up && gSpriteCanJump) // Start new jump
- {
- if (spriteIsOnGround)
- {
- srcSpriteP->vertMoveDelta = -kJumpSpeed;
- gSpriteIsJumping = true;
- gSpriteCanJump = false;
- gSpriteJumpStage = 0;
- }
- }
- else // Stopped jumping, so make it fall early
- {
- if (srcSpriteP->vertMoveDelta < 0)
- srcSpriteP->vertMoveDelta += 3;
-
- gSpriteIsJumping = false;
-
- if (!gKeys.up && srcSpriteP->vertMoveDelta >= 0)
- gSpriteCanJump = true;
- }
-
- // Add gravity
- srcSpriteP->vertMoveDelta += kGravitySpeed;
-
- // Keep ball from falling too fast
- if (srcSpriteP->vertMoveDelta > kMaxFallSpeed)
- srcSpriteP->vertMoveDelta = kMaxFallSpeed;
-
-
-
- srcSpriteP->destFrameRect.top += srcSpriteP->vertMoveDelta;
- srcSpriteP->destFrameRect.bottom += srcSpriteP->vertMoveDelta;
- tempHorizDelta = 0;
-
-
- // Check for collisions with walls vertically
- if (srcSpriteP->vertMoveDelta > 0) // Moving down
- {
- // Make sure sprite was above the tile before we fell through it. Otherwise,
- // the sprite was never on top, and shouldn't be moved by the platform.
- if ( ((srcSpriteP->oldFrameRect.bottom-1) / kTileHeight) <
- ((srcSpriteP->destFrameRect.bottom-1) / kTileHeight) )
- {
- // Check for floors moving left
- if ( SWCheckSpriteWithTiles(gSpriteWorldP, srcSpriteP, kSWBottomSide,
- &gSpriteInsetRect, 0, 0, kFirstLeftFloorTile, kFirstLeftFloorTile, false) )
- {
- tempHorizDelta -= kMovingFloorForce;
- }
-
- // Check for floors moving right
- if ( SWCheckSpriteWithTiles(gSpriteWorldP, srcSpriteP, kSWBottomSide,
- &gSpriteInsetRect, 0, 0, kFirstRightFloorTile, kFirstRightFloorTile, false) )
- {
- tempHorizDelta += kMovingFloorForce;
- }
- }
-
- // Keep sprite from falling through moving floors
- if ( SWCheckSpriteWithTiles(gSpriteWorldP, srcSpriteP, kSWBottomSide,
- &gSpriteInsetRect, 0, 0, kFirstLeftFloorTile, kFirstRightFloorTile, true) )
- {
- srcSpriteP->vertMoveDelta = 0;
- }
- // Keep sprite from falling through a changing floor
- else if ( gChangingFloorMode == true &&
- SWCheckSpriteWithTiles(gSpriteWorldP, srcSpriteP, kSWBottomSide,
- &gSpriteInsetRect, 0, 0, kFirstChangingTile, kFirstChangingTile, true) )
- {
- srcSpriteP->vertMoveDelta = 0;
- }
-
- // Make sure sprite doesn't fall through any walls
- if ( SWCheckSpriteWithTiles(gSpriteWorldP, srcSpriteP, kSWBottomSide,
- &gSpriteInsetRect, 0, 0, kFirstWallTile, kLastWallTile, true) )
- {
- srcSpriteP->vertMoveDelta = 0;
- }
- }
- else if (srcSpriteP->vertMoveDelta < 0) // Moving up
- {
- if ( SWCheckSpriteWithTiles(gSpriteWorldP, srcSpriteP, kSWTopSide,
- &gSpriteInsetRect, 0, 0, kFirstWallTile, kLastWallTile, true) )
- {
- srcSpriteP->vertMoveDelta /= 2;
- gSpriteIsJumping = false;
- }
- }
-
-
- srcSpriteP->destFrameRect.right += srcSpriteP->horizMoveDelta + tempHorizDelta;
- srcSpriteP->destFrameRect.left += srcSpriteP->horizMoveDelta + tempHorizDelta;
-
- // Check for collisions with walls horizontally
- if (srcSpriteP->horizMoveDelta + tempHorizDelta > 0) // Moving right
- {
- if ( SWCheckSpriteWithTiles(gSpriteWorldP, srcSpriteP, kSWRightSide,
- &gSpriteInsetRect, 0, 0, kFirstWallTile, kLastWallTile, true) )
- {
- if (srcSpriteP->horizMoveDelta > 0)
- srcSpriteP->horizMoveDelta = 1;
- }
- }
- else if (srcSpriteP->horizMoveDelta + tempHorizDelta < 0) // Moving left
- {
- if ( SWCheckSpriteWithTiles(gSpriteWorldP, srcSpriteP, kSWLeftSide,
- &gSpriteInsetRect, 0, 0, kFirstWallTile, kLastWallTile, true) )
- {
- if (srcSpriteP->horizMoveDelta < 0)
- srcSpriteP->horizMoveDelta = -1;
- }
- }
-
- srcSpriteP->needsToBeDrawn = true;
-
-
- // See if sprite hit exit sign or spikes
- if (SWCheckSpriteWithTiles(gSpriteWorldP, gSimpleSpriteP, kSWEntireSprite,
- &gSpriteInsetRect, 0, 0, kFirstExitTile, kLastExitTile, false) )
- {
- gSpriteHitExit = true;
- }
- else if (gSpikesAreUp && SWCheckSpriteWithTiles(gSpriteWorldP, gSimpleSpriteP,
- kSWEntireSprite, &gSpriteInsetRect, 0, 0, kFirstSpikeTile, kLastSpikeTile, false) )
- {
- gSpriteWasKilled = true;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // TileChangeProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void TileChangeProc(SpriteWorldPtr spriteWorldP)
- {
- short curImage;
- static short wallDelay = 0, spikeTimer = 0, spikeDirection = 0, spikeDelay = 0;
- static short changingFloorDelay = 0, changingFloorWait = 0, exitDelay = 0;
- static Boolean spikesAreMoving = false;
- static short oldTicks = 0;
- short ticksPassed, ticks;
-
- // Initialize oldTicks the first time this function is called
- if (oldTicks == 0)
- oldTicks = TickCount();
-
- ticks = TickCount();
- ticksPassed = ticks - oldTicks; // Number of ticks passed since last call
- oldTicks = ticks;
-
- changingFloorWait += ticksPassed;
- if (changingFloorWait >= kChangingFloorWait)
- {
- changingFloorWait = 0;
- if (gChangingFloorMode == true)
- {
- gChangingFloorMode = 0;
- SWChangeTileImage(spriteWorldP, kFirstChangingTile, kBackgroundTile);
- }
- else
- {
- gChangingFloorMode = 1;
- SWChangeTileImage(spriteWorldP, kFirstChangingTile, kFirstChangingTile);
- }
- }
-
- // Change the changing floor
- if (gChangingFloorMode == true)
- {
- changingFloorDelay += ticksPassed;
- if (changingFloorDelay >= kChangingFloorSpeed)
- {
- curImage = spriteWorldP->curTileImage[kFirstChangingTile];
- if (curImage < kLastChangingTile)
- curImage++;
- else
- curImage = kFirstChangingTile;
-
- SWChangeTileImage(spriteWorldP, kFirstChangingTile, curImage);
- changingFloorDelay = 0;
- }
- }
-
- // Change the moving floors
- wallDelay += ticksPassed;
- if (wallDelay >= kMovingFloorSpeed)
- {
- // Move the left wall
- curImage = spriteWorldP->curTileImage[kFirstLeftFloorTile];
- if (curImage < kLastLeftFloorTile)
- curImage++;
- else
- curImage = kFirstLeftFloorTile;
-
- SWChangeTileImage(spriteWorldP, kFirstLeftFloorTile, curImage);
-
- // Move the right wall
- curImage = spriteWorldP->curTileImage[kFirstRightFloorTile];
- if (curImage < kLastRightFloorTile)
- curImage++;
- else
- curImage = kFirstRightFloorTile;
-
- SWChangeTileImage(spriteWorldP, kFirstRightFloorTile, curImage);
-
- wallDelay = 0;
- }
-
-
- // Change the spikes
- if (spikesAreMoving)
- {
- spikeDelay += ticksPassed;
- if (spikeDelay >= kSpikeSpeed)
- {
- curImage = spriteWorldP->curTileImage[kFirstSpikeTile];
- curImage += spikeDirection;
- if (curImage == kLastSpikeTile+1 || curImage == kFirstSpikeTile)
- {
- spikesAreMoving = false;
- if (spikeDirection > 0)
- spikeDirection = -1;
- else
- spikeDirection = 1;
- }
-
- // Determine whether the current spike position can kill the sprite
- if (curImage > kFirstSpikeTile + 7)
- gSpikesAreUp = false;
- else
- gSpikesAreUp = true;
-
- SWChangeTileImage(spriteWorldP, kFirstSpikeTile, curImage);
- spikeDelay = 0;
- }
- }
- else
- {
- spikeTimer += ticksPassed;
- if (spikeTimer > kSpikeChangeDelay)
- {
- spikeTimer = 0;
- spikesAreMoving = true;
- }
- }
-
-
- // Animate the exit sign
- exitDelay += ticksPassed;
- if (exitDelay >= kExitSignSpeed)
- {
- curImage = spriteWorldP->curTileImage[kFirstExitTile];
- if (curImage < kLastExitTile)
- curImage++;
- else
- curImage = kFirstExitTile;
-
- SWChangeTileImage(spriteWorldP, kFirstExitTile, curImage);
- exitDelay = 0;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SmoothScrollingWorldMoveProc - our scrolling WorldMoveProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SmoothScrollingWorldMoveProc(
- SpriteWorldPtr spriteWorldP,
- SpritePtr followSpriteP)
- {
- short screenMidRectTop, screenMidRectLeft;
-
- screenMidRectTop = gScreenMidRect.top + spriteWorldP->visScrollRect.top;
- screenMidRectLeft = gScreenMidRect.left + spriteWorldP->visScrollRect.left;
-
-
- spriteWorldP->horizScrollDelta = (kMaxWalkSpeed *
- (followSpriteP->destFrameRect.left - screenMidRectLeft) ) / kSpriteMoveDistance;
-
- spriteWorldP->vertScrollDelta = (kMaxFallSpeed *
- (followSpriteP->destFrameRect.top - screenMidRectTop) ) / kSpriteMoveDistance;
-
- if (kInterlacedMode)
- spriteWorldP->vertScrollDelta = spriteWorldP->vertScrollDelta>>1<<1;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // UpdateKeys (Put the latest key values in the keys structure)
- ///--------------------------------------------------------------------------------------
-
- void UpdateKeys( void )
- {
- EventRecord event;
- short theKey;
- Boolean isDown;
-
-
- while ( GetOSEvent( (keyUpMask | keyDownMask), &event ) )
- {
- theKey = (event.message & keyCodeMask) >> 8;
- isDown = (event.what != keyUp);
-
- if ( (theKey == kLeftArrowKey) || (theKey == kLeftKeyPad) )
- gKeys.left = isDown;
- else if ( (theKey == kRightArrowKey) || (theKey == kRightKeyPad) )
- gKeys.right = isDown;
- else if ( (theKey == kDownArrowKey) || (theKey == kDownKeyPad) )
- gKeys.down = isDown;
- else if ( (theKey == kUpArrowKey) || (theKey == kUpKeyPad) )
- gKeys.up = isDown;
- else if (theKey == kEscKey)
- gEscapeKey = isDown;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ResetKeys (Called when setting up a new game)
- ///--------------------------------------------------------------------------------------
-
- void ResetKeys( void )
- {
- gKeys.left = 0;
- gKeys.right = 0;
- gKeys.down = 0;
- gKeys.up = 0;
- gEscapeKey = 0;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // AdvanceLevel
- ///--------------------------------------------------------------------------------------
-
- void AdvanceLevel( void )
- {
- Rect moveBoundsRect;
- unsigned long junkTime;
- OSErr err;
-
- gCurrentLevel++;
- gSpriteHitExit = false;
-
- SWDisposeTileMap(&gTileMapStructP);
- err = SWLoadTileMap(&gTileMapStructP, gCurrentLevel);
- if (err)
- {
- gCurrentLevel = 128;
- SWClearStickyError(); // Clear the sticky error that was set when the level didn't load.
- err = SWLoadTileMap(&gTileMapStructP, gCurrentLevel);
- FatalError(err);
- }
-
- gTileMap = gTileMapStructP->tileMap;
- SWInstallTileMap(gSpriteWorldP, gTileMapStructP, 0);
-
- // Reset scrolling moveBounds for new TileMap
- SetRect(&moveBoundsRect, 0, 0,
- gTileMapStructP->numCols * kTileWidth,
- gTileMapStructP->numRows * kTileHeight);
- SWSetScrollingWorldMoveBounds(gSpriteWorldP, &moveBoundsRect);
-
-
- ResetSprite();
- Delay(30, &junkTime);
-
- SWDrawTilesInBackground(gSpriteWorldP);
- SWUpdateSpriteWorld(gSpriteWorldP, false);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // KillSprite
- ///--------------------------------------------------------------------------------------
-
- void KillSprite( void )
- {
- unsigned long dummyTicks;
-
- gSpriteWasKilled = false;
- SWSetSpriteFrameTime(gSimpleSpriteP, 1000/15);
- SWSetSpriteFrameAdvance(gSimpleSpriteP, 1);
- SWSetSpriteMoveProc(gSimpleSpriteP, NULL);
-
- do
- { // Run the "popped ball" animation
- SWProcessScrollingSpriteWorld(gSpriteWorldP);
- SWAnimateScrollingSpriteWorld(gSpriteWorldP);
- } while (gSimpleSpriteP->curFrameIndex < gSimpleSpriteP->maxFrames-1 && !Button());
-
- Delay(23, &dummyTicks);
- ResetSprite();
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ResetSprite
- ///--------------------------------------------------------------------------------------
-
- void ResetSprite( void )
- {
- SWSetSpriteMoveDelta(gSimpleSpriteP, 0, 0);
- SWMoveSprite(gSimpleSpriteP, kStartCol * kTileWidth, kStartRow * kTileHeight);
- SWMoveVisScrollRect(gSpriteWorldP, 0, 0);
-
- SWSetSpriteFrameAdvance(gSimpleSpriteP, 0);
- SWSetSpriteMoveProc(gSimpleSpriteP, KeySpriteMoveProc);
- SWSetCurrentFrameIndex(gSimpleSpriteP, 0);
-
- gSpriteCanJump = false;
- gSpriteIsJumping = false;
- gSpriteJumpStage = 0;
- }
-